﻿/*
 * timetrigger.cpp
 *
 *  Created on: 2017年7月13日
 *      Author: work
 */

#include "timetrigger.hpp"
#include <dm/os/log/logger.hpp>

namespace dm{
namespace app{

static const char* logModule = "CTimeTrigger.hisdata.app.dm";

CTimeTrigger::CTimeTrigger():m_cycle(Yearly),m_timeInfo(),m_nextTime(){
	log().debug(THISMODULE "创建对象");
}

CTimeTrigger::CTimeTrigger( const CTimeTrigger& trigger ):m_cycle(trigger.m_cycle),
		m_timeInfo(trigger.m_timeInfo),m_nextTime(trigger.m_nextTime){
}

CTimeTrigger& CTimeTrigger::operator =( const CTimeTrigger& trigger ){
	m_cycle = trigger.m_cycle;
	m_timeInfo = trigger.m_timeInfo;
	m_nextTime = trigger.m_nextTime;

	return *this;
}

void CTimeTrigger::setCycle( const ECycle& cycle ){
	m_cycle = cycle;
}

void CTimeTrigger::setTimeInfo( const dm::CDateTime& info ){
	m_timeInfo = info;
}

void CTimeTrigger::init(){
	dm::CTimeStamp now = dm::CTimeStamp::cur();
	dm::CDateTime n = now;

	switch( m_cycle ){
	case Yearly:
		n.setMonth( m_timeInfo.month() );
		n.setDay( m_timeInfo.day() );
		n.setHour( m_timeInfo.hour() );
		n.setMinute( m_timeInfo.minute() );
		n.setSec( m_timeInfo.sec() );
		n.setMsec( m_timeInfo.msec() );

		n.toTimeStamp(m_nextTime);
		if( m_nextTime<now ){
			n.setYear( n.year()+1 );
			n.toTimeStamp(m_nextTime);
		}

		log().info(THISMODULE "每年执行一次。设定下次触发时刻为%s",n.toString().c_str());

		break;
	case Monthly:
		n.setDay( m_timeInfo.day() );
		n.setHour( m_timeInfo.hour() );
		n.setMinute( m_timeInfo.minute() );
		n.setSec( m_timeInfo.sec() );
		n.setMsec( m_timeInfo.msec() );

		n.toTimeStamp(m_nextTime);
		if( m_nextTime<now ){
			if( n.month()==12 ){
				n.setYear( n.year()+1 );
				n.setMonth(1);
			}else
				n.setMonth( n.month()+1 );

			n.toTimeStamp(m_nextTime);
		}

		log().info(THISMODULE "每月执行一次。设定下次触发时刻为%s",n.toString().c_str());
		break;
	case Daily:
		n.setHour( m_timeInfo.hour() );
		n.setMinute( m_timeInfo.minute() );
		n.setSec( m_timeInfo.sec() );
		n.setMsec( m_timeInfo.msec() );

		n.toTimeStamp(m_nextTime);
		if( m_nextTime<now )
			m_nextTime.setSeconds( m_nextTime.seconds()+24*60*60 );

		n = m_nextTime;

		log().info(THISMODULE "每日执行一次。设定下次触发时刻为%s",n.toString().c_str());
		break;
	case Hourly:
		n.setMinute( m_timeInfo.minute() );
		n.setSec( m_timeInfo.sec() );
		n.setMsec( m_timeInfo.msec() );
		n.toTimeStamp(m_nextTime);

		if( m_nextTime<now )
			m_nextTime.setSeconds( m_nextTime.seconds()+60*60 );

		n = m_nextTime;

		log().info(THISMODULE "每小时执行一次。设定下次触发时刻为%s",n.toString().c_str());
		break;
	case Minutely:
		n.setSec( m_timeInfo.sec() );
		n.setMsec( m_timeInfo.msec() );
		n.toTimeStamp(m_nextTime);

		if( m_nextTime<now )
			m_nextTime.setSeconds( m_nextTime.seconds()+60 );

		n = m_nextTime;

		log().info(THISMODULE "每分钟执行一次。设定下次触发时刻为%s",n.toString().c_str());
		break;
	default:
		log().warnning(THISMODULE "未知周期类型：%d",m_cycle);
	}
}

const dm::CTimeStamp& CTimeTrigger::nextTime( const dm::CTimeStamp& now ){
	if( now>m_nextTime ){
		dm::CDateTime n = now;
		switch( m_cycle ){
		case Yearly:
			n.setYear( n.year()+1 );
			n.setMonth( m_timeInfo.month() );
			n.setDay( m_timeInfo.day() );
			n.setHour( m_timeInfo.hour() );
			n.setMinute( m_timeInfo.minute() );
			n.setSec( m_timeInfo.sec() );
			n.setMsec( m_timeInfo.msec() );
			n.toTimeStamp(m_nextTime);
			log().info(THISMODULE "每年执行一次。设定下次触发时刻为%s",n.toString().c_str());
			break;
		case Monthly:
			if( n.month()==12 ){
				n.setYear( n.year()+1 );
				n.setMonth(1);
			}else
				n.setMonth( n.month()+1 );

			n.setDay( m_timeInfo.day() );
			n.setHour( m_timeInfo.hour() );
			n.setMinute( m_timeInfo.minute() );
			n.setSec( m_timeInfo.sec() );
			n.setMsec( m_timeInfo.msec() );
			n.toTimeStamp(m_nextTime);

			log().info(THISMODULE "每月执行一次。设定下次触发时刻为%s",n.toString().c_str());
			break;
		case Daily:
			n.setHour( m_timeInfo.hour() );
			n.setMinute( m_timeInfo.minute() );
			n.setSec( m_timeInfo.sec() );
			n.setMsec( m_timeInfo.msec() );
			n.toTimeStamp(m_nextTime);

			m_nextTime.setSeconds( m_nextTime.seconds()+24*60*60 );

			n = m_nextTime;

			log().info(THISMODULE "每日执行一次。设定下次触发时刻为%s",n.toString().c_str());
			break;
		case Hourly:
			n.setMinute( m_timeInfo.minute() );
			n.setSec( m_timeInfo.sec() );
			n.setMsec( m_timeInfo.msec() );
			n.toTimeStamp(m_nextTime);

			m_nextTime.setSeconds( m_nextTime.seconds()+60*60 );

			n = m_nextTime;

			log().info(THISMODULE "每小时执行一次。设定下次触发时刻为%s",n.toString().c_str());
			break;
		case Minutely:
			n.setSec( m_timeInfo.sec() );
			n.setMsec( m_timeInfo.msec() );
			n.toTimeStamp(m_nextTime);

			m_nextTime.setSeconds( m_nextTime.seconds()+60 );

			n = m_nextTime;

			log().info(THISMODULE "每分钟执行一次。设定下次触发时刻为%s",n.toString().c_str());
			break;
		default:
			log().warnning(THISMODULE "未知周期类型：%d",m_cycle);
		}
	}

	return m_nextTime;
}

}
}
